﻿namespace MicroCloud.Api.Authorization.Areas.Admin.Controllers.Auth
{
    /// <summary>
    /// 用户数据权限管理
    /// </summary>
    [Description("用户数据权限管理")]
    [ModuleInfo(Code = "UserEntity", Name = "用户数据权限管理", OrderNo = 6, Position = "Auth", PositionName = "授权模块")]
    public class UserEntityController : AdminControllerBase
    {
        #region "属性"
        #region "获取 数据权限管理器"
        /// <summary>
        /// 获取 数据权限管理器
        /// </summary>
        protected DataAuthManager DataAuthManager => ServiceProvider.GetService<DataAuthManager>();
        #endregion

        #endregion

        #region "Action方法"
        #region "读取用户数据权限"
        /// <summary>
        /// 读取用户数据权限
        /// </summary>
        /// <param name="request">页请求信息</param>
        /// <returns>用户数据权限列表分页信息</returns>
        [HttpPost]
        [ModuleInfo]
        [DependOnFunction("ReadNode", Controller = "User")]
        [DependOnFunction(nameof(EntityInfoController.ReadProperties), Controller = nameof(EntityInfoController))]
        [Description("读取")]
        public virtual PageData<EntityUserOutputDto> Read(PageRequest request)
        {
            Check.NotNull(request, nameof(request));
            IFunction function = this.GetExecuteFunction();

            Expression<Func<EntityUser, bool>> predicate = FilterService.GetExpression<EntityUser>(request.FilterGroup);
            request.AddDefaultSortCondition(new SortCondition("UserId"), new SortCondition("EntityId"), new SortCondition("Operation"));
            //if (request.PageCondition.SortConditions.Length == 0)
            //{
            //    request.PageCondition.SortConditions = new[]
            //    {
            //        new SortCondition("UserId"),
            //        new SortCondition("EntityId"),
            //        new SortCondition("Operation")
            //    };
            //}

            //UserManager<User> userManager = HttpContext.RequestServices.GetService<UserManager<User>>();
            Func<EntityUser, bool> updateFunc = FilterService.GetDataFilterExpression<EntityUser>(null, DataAuthOperation.Update).Compile();
            Func<EntityUser, bool> deleteFunc = FilterService.GetDataFilterExpression<EntityUser>(null, DataAuthOperation.Delete).Compile();
            //var page = DataAuthManager.EntityUsers.ToPage(predicate,
            //    request.PageCondition,
            //    m => new
            //    {
            //        D = m,
            //        userManager.Users.First(n => n.Id == m.UserId).UserName,
            //        UserNickName = m.User.NickName,
            //        EntityName = m.EntityInfo.Name,
            //        EntityType = m.EntityInfo.TypeName,
            //    }).ToPageResult(data => data.Select(m => new EntityUserOutputDto(m.D)
            //    {
            //        UserName = m.UserName,
            //        UserNickName = m.UserNickName,
            //        EntityName = m.EntityName,
            //        EntityType = m.EntityType,
            //        Updatable = updateFunc(m.D),
            //        Deletable = deleteFunc(m.D)
            //    }).ToArray());

            PageResult<EntityUserOutputDto> page;
            using (var scope = ServiceProvider.CreateScope())
            {
                var userRepository = scope.ServiceProvider.GetService<IRepository<User, long>>();
                var entityInfoRepository = scope.ServiceProvider.GetService<IRepository<EntityInfo, long>>();

                page = CacheService.ToPageCache(DataAuthManager.EntityUsers, predicate, request.PageCondition, m => new
                {
                    D = m,
                    GetUser(userRepository, m.UserId).UserName,
                    UserNickname = GetUser(userRepository, m.UserId).NickName,
                    EntityName = GetEntityInfo(entityInfoRepository, m.EntityId).Name,
                    EntityType = GetEntityInfo(entityInfoRepository, m.EntityId).TypeName,
                }, function).ToPageResult(data => data.Select(m => new EntityUserOutputDto(m.D)
                {
                    UserName = m.UserName,
                    UserNickname = m.UserNickname,
                    EntityName = m.EntityName,
                    EntityType = m.EntityType,
                    Updatable = updateFunc(m.D),
                    Deletable = deleteFunc(m.D)
                }).ToArray());
            }

            return page.ToPageData();
        }
        #endregion

        #region "新增用户数据权限"
        /// <summary>
        /// 新增用户数据权限
        /// </summary>
        /// <param name="dtos">用户数据权限信息</param>
        /// <returns>JSON操作结果</returns>
        [HttpPost]
        [ModuleInfo]
        [DependOnFunction(nameof(Read))]
        [DependOnFunction("ReadNode", Controller = "User")]
        [DependOnFunction(nameof(EntityInfoController.ReadNode), Controller = nameof(EntityInfoController))]
        [UnitOfWork]
        [Description("新增")]
        public virtual async Task<AjaxResult> Create(params EntityUserInputDto[] dtos)
        {
            Check.NotNull(dtos, nameof(dtos));

            OperationResult result = await DataAuthManager.CreateEntityUsers(dtos);
            return result.ToAjaxResult(true);
        }
        #endregion
        #region "更新用户数据权限"
        /// <summary>
        /// 更新用户数据权限
        /// </summary>
        /// <param name="dtos">用户数据权限信息</param>
        /// <returns>JSON操作结果</returns>
        [HttpPost]
        [ModuleInfo]
        [DependOnFunction(nameof(Read))]
        [DependOnFunction("ReadNode", Controller = "User")]
        [DependOnFunction(nameof(EntityInfoController.ReadNode), Controller = nameof(EntityInfoController))]
        [UnitOfWork]
        [Description("更新")]
        public virtual async Task<AjaxResult> Update(params EntityUserInputDto[] dtos)
        {
            Check.NotNull(dtos, nameof(dtos));
            OperationResult result = await DataAuthManager.UpdateEntityUsers(dtos);
            return result.ToAjaxResult(true);
        }
        #endregion
        #region "删除用户数据权限"
        /// <summary>
        /// 删除用户数据权限
        /// </summary>
        /// <param name="ids">用户数据权限编号</param>
        /// <returns>JSON操作结果</returns>
        [HttpPost]
        [ModuleInfo]
        [DependOnFunction(nameof(Read))]
        [UnitOfWork]
        [Description("删除")]
        public virtual async Task<AjaxResult> Delete(params long[] ids)
        {
            Check.NotNull(ids, nameof(ids));

            OperationResult result = await DataAuthManager.DeleteEntityUsers(ids);
            return result.ToAjaxResult();
        }
        #endregion

        #endregion

        #region "受保护的方法"
        #region "获取用户信息"
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userRepository">用户仓储模型</param>
        /// <param name="userId">用户编号</param>
        /// <returns></returns>
        [NonAction]
        [NonFunction]
        protected static UserSimpleDto GetUser(IRepository<User, long> userRepository, long? userId)
        {
            if (userId == null)
            {
                return new UserSimpleDto();
            }
            
            var user = userRepository.QueryAsNoTracking(o => o.Id == userId).ToCacheFirst<User, UserSimpleDto>(10, false, nameof(UserSimpleDto));
            return user ?? new UserSimpleDto();
        }
        #endregion
        #region "获取实体信息"
        /// <summary>
        /// 获取实体信息
        /// </summary>
        /// <param name="entityInfoRepository">实体信息仓储模型</param>
        /// <param name="entityId">数据编号</param>
        /// <returns></returns>
        [NonAction]
        [NonFunction]
        protected static EntityInfo GetEntityInfo(IRepository<EntityInfo, long> entityInfoRepository, long? entityId)
        {
            if (entityId == null)
            {
                return new EntityInfo();
            }
            var entityInfo = entityInfoRepository.ToCacheFirst(o => o.Id == entityId, false, 10, false);
            return entityInfo ?? new EntityInfo();
        }
        #endregion

        #endregion

    }

}
